package org.ouwh.oowiki.http;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.ouwh.fw.model.data.Struct;
import org.ouwh.oowiki.ctrl.ControllerDispatcher;
import org.ouwh.oowiki.ctrl.ErrorCodes;

public class InvokeHandler extends AbstractHandler {
	private static Log log = LogFactory.getLog(InvokeHandler.class);

	public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		if (log.isDebugEnabled()) {
			Enumeration<?> e = request.getHeaderNames();
			while (e.hasMoreElements()) {
				String name = e.nextElement().toString();
				log.debug(name + ": " + request.getHeader(name));
			}
		}
		HttpRequestParser parser = new HttpRequestParser();
		MyRequest myRequest = null;
		MyResponse myResponse = null;
		try {
			myRequest = parser.parse(request);
			ControllerDispatcher dispatcher = new ControllerDispatcher();
			myResponse = dispatcher.handle(target, myRequest);
		} catch (MyException e) {
			if (e.getErrorCode() == ErrorCodes.UN_AUTHENTICATE.getCode()) {
				response.sendRedirect("/author");
			}
			myResponse = handleMyException(request, response, e);
		} catch (Exception e) {
			log.error("handle http request failed: ", e);
			myResponse = handleException(request, response, e);
		}
		if (myResponse != null) {
			HttpResponsePresenter presenter = new HttpResponsePresenter();
			try {
				presenter.present(response, myResponse);
			} catch (Exception e) {
				log.error("present http response failed: ", e);
			}
		}
	}

	private MyResponse handleMyException(HttpServletRequest request, HttpServletResponse response, MyException e) {
		MyResponse resp = new MyResponse();
		Struct struct = new Struct("response");
		struct.addData("code", ((MyException) e).getErrorCode());
		struct.addData("message", e.getMessage());
		resp.setResults(struct);
		return resp;
	}

	private MyResponse handleException(HttpServletRequest request, HttpServletResponse response, Exception e) {
		MyResponse resp = new MyResponse();
		Struct struct = new Struct("response");
		struct.addData("code", 500);
		struct.addData("message", e.getMessage());
		resp.setResults(struct);
		return resp;
	}
}